package org.example;

import cn.hutool.core.io.resource.ResourceUtil;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.List;
import java.util.Properties;

public class XMLConfigBuilder {

    private String resource;

    private Element root;


    private Configuration configuration;

    public XMLConfigBuilder(String resource) {
        this.resource = resource;
    }




    private Reader parseRoot() {
        InputStream stream = ResourceUtil.getStream(resource);
        return new InputStreamReader(stream);
    }


    public Configuration parse() throws DocumentException {
        // 读取文件流
        Reader reader = parseRoot();

        SAXReader config = new SAXReader();
        Document document = config.read(reader);
        root = document.getRootElement();
        configuration = new Configuration();
        // 读取数据库配置信息
        this.parseEnvironment(root.element("environments"));

        // 读取Mapper
        this.parseMappersElement(root.element("mappers"));

        return configuration;

    }




    private void parseEnvironment(Element element) {
        Environment environment;
        String defaultValue = element.attributeValue("default");
        List<Element> elements = element.elements("environment");
        for (Element e : elements) {
            String id = e.attributeValue("id");
            if(!defaultValue.equals(id)) {
                continue;
            }
            Element transactionManager = e.element("transactionManager");
            String type = transactionManager.attributeValue("type");
            Class<?> transactionFactoryType = configuration.getType(type);
            Element dataSource = e.element("dataSource");
            String dataSourceType = dataSource.attributeValue("type");
            Class<?> aClass = configuration.getType(dataSourceType);
            List<Element> property = dataSource.elements("property");
            Properties properties = new Properties();
            for (Element p : property) {
                String name = p.attributeValue("name");
                String value = p.attributeValue("value");
                properties.put(name,value);
            }
            try {
                TransactionFactory transactionFactory = (TransactionFactory) transactionFactoryType.newInstance();
                DataSourceFactory dataSourceInstance = (DataSourceFactory) aClass.newInstance();
                dataSourceInstance.setProperties(properties);
                environment = new Environment(id,transactionFactory,dataSourceInstance.getDataSource());
                configuration.setEnvironment(environment);
            } catch (InstantiationException | IllegalAccessException exception) {
                throw new RuntimeException("创建事务工厂或数据源失败,当前的事务工厂类型为: " + type + "  数据源类型为: " + dataSourceType);
            }
        }
    }




    private void parseMappersElement(Element element) {
        List<Element> mappers = element.elements("mapper");
        if(mappers == null || mappers.isEmpty()) {
            return;
        }
        for (Element mp : mappers) {
            String resource = mp.attributeValue("resource");
            XmlMapperBuilder builder = new XmlMapperBuilder(resource, configuration);
            builder.parse();
        }

    }
















}
